<template>
  <div class="container" ref="container">
    <div class="box"></div>
  </div>
</template>
<script setup lang="ts">
import * as THREE from 'three'
// 导入轨道控制器
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
import { PointerLockControls } from 'three/examples/jsm/controls/PointerLockControls'
// 引入性能监视器
import Stats from 'three/examples/jsm/libs/stats.module.js'
// 导入动画库
import gsap from 'gsap'
// 导入dat.gui
import * as dat from 'dat.gui'

import { onMounted, ref } from 'vue'
// import { RouterLink, RouterView } from 'vue-router'

const container: any = ref(null)
// 创建性能监视器
const stats = new (<any>Stats)()

// 创建场景
const scene = new THREE.Scene()
scene.background = new THREE.Color('rgb(0,47,167)')

// 创建相机
const camera = new THREE.PerspectiveCamera(
  100,
  window.innerWidth / (window.innerHeight - 1),
  0.1,
  1000
)
// 默认情况下，当我们调用scene.add()的时候，物体将会被添加到(0,0,0)坐标。
// 但将使得摄像机和立方体彼此在一起。为了防止这种情况的发生，我们只需要将摄像机稍微向外移动一些即可。
camera.position.set(0, 10, 100)

// 坐标网格
const gridHelper = new THREE.GridHelper(
  1000,
  100,
  new THREE.Color('#F7F7F7'),
  new THREE.Color('#F7F7F7')
)
scene.add(gridHelper)

// 创建渲染器
const renderer = new THREE.WebGLRenderer({
  precision: 'highp', //着色器精度
  antialias: true //抗锯齿
})
// 设置渲染器尺寸
renderer.setSize(window.innerWidth, window.innerHeight - 1)

// 轨道控制器
const orbitControls = new OrbitControls(camera, renderer.domElement)
orbitControls.update()

function animate() {
  box.rotateY(0.01)
  // group.rotateY(0.01)
  requestAnimationFrame(animate)
  renderer.render(scene, camera)
  stats.update()
  orbitControls.update()
}

// 画面尺寸变化
window.addEventListener('resize', () => {
  console.log('尺寸变化')
  // 摄像机视锥体的长宽比，通常是使用画布的宽/画布的高。默认值是1（正方形画布）。
  camera.aspect = window.innerWidth / (window.innerHeight - 1)
  camera.updateProjectionMatrix()
  //渲染器宽高比
  renderer.setSize(window.innerWidth, window.innerHeight - 1)
  renderer.setPixelRatio(window.devicePixelRatio)
})

// 创建一个立方体
const geometry = new THREE.BoxGeometry(10, 10, 10)
const material = new THREE.MeshBasicMaterial({
  color: 0xff00ff
})
const box = new THREE.Mesh(geometry, material)

// 创建一个球
const sphereGeometry = new THREE.SphereGeometry(10)
const sphere = new THREE.Mesh(sphereGeometry, material)
sphere.translateY(20)
// 创建一个组
const group = new THREE.Group()
group.add(box, sphere) //将box添加到父对象中
scene.add(group)

// 创建辅助坐标
const axesHelper = new THREE.AxesHelper(20)
scene.add(axesHelper)

/**
 *  移除对象和隐藏对象的区别：
 *    移除对象后，children中会删除相应的对象。
 *    而隐藏对象只是将visible改为false，对象仍然存在于children中
 */

// 移除对象 移除了方形和辅助坐标系
// group.remove(box)
// scene.remove(axesHelper)
// console.log('scene:', scene)

// 隐藏对象
// scene.visible = false
// group.visible = false
// box.visible = false
// sphere.visible = false
// console.log('scene:', scene)

// 注意:如果多个模型引用了同一个材质，如果该材质.visible设置为false，意味着隐藏绑定该材质的所有模型。
// material.visible = false

// 页面挂载后渲染
onMounted(() => {
  console.log(container.value)
  container.value?.appendChild(renderer.domElement)
  container.value?.appendChild(stats.domElement) //性能监视器
  animate()
})
</script>
<style scoped>
.box {
  width: 100px;
  height: 100px;
  position: absolute;
}
</style>
